#!/usr/bin/perl -w
use strict;
my $array_ref = my_read_file($ARGV[0]);
my $fileout = $ARGV[1];
my @battleInfo = @$array_ref;
my $hash_ref1 = $battleInfo[0];
my $hash_ref2 = $battleInfo[1];
my %competitor1 = %$hash_ref1;
my %competitor2 = %$hash_ref2;
my $random = int(rand(2)) + 1;
my $roundCount = 1;
my $alive = 1;

open RESULT, ">>$fileout" or die "Cannot write to file";


#If HP field not provided or not a digit, set default
if(!(exists $competitor1{HP})|| !($competitor1{HP} =~ m/^[\d]+$/)){
  $competitor1{HP} = 40;
}
if(!(exists $competitor2{HP}) || !($competitor2{HP} =~ m/^[\d]+$/)){
  $competitor2{HP} = 40;
}


#Introduce the match
print "$competitor1{Name} vs. $competitor2{Name} \n";

#While they are both alive continue battle
while(($competitor1{HP} > 0) && ($competitor2{HP} > 0) && $alive){
  #Print round Info and status of players
  print "Round $roundCount \n";
  $roundCount ++;
  print "Current Hit Points: $competitor1{Name} : $competitor1{HP}  $competitor2{Name} : $competitor2{HP} \n";

  #Do battle!
  if($random == 1){
    my $hit = $competitor1{POW} + int(rand(10)) + 1 - $competitor2{DEF};
    if($hit > 0){
      my $dmg = int(($competitor1{POW} + int(rand(5))+1)/4);
      print $competitor1{Name}." casts magic missiles first, and hits for $dmg \n";
      $competitor2{HP} -= $dmg;
      if($competitor2{HP} < 1){
	$alive = 0;
	next;
      }
    }
    else{
      print $competitor1{Name}." casts magic missiles first, and misses \n";
    }
    $hit = $competitor2{POW} + int(rand(10)) + 1 - $competitor1{DEF};
    if($hit > 0){
      my $dmg = int(($competitor2{POW} +int(rand(5)) + 1)/4);
      print $competitor2{Name}." casts magic missiles, and hits for $dmg \n";
      $competitor1{HP} -= $dmg;
      if($competitor1{HP} < 1){
	$alive = 0;
	next;
      }
    }
    else{
      print $competitor2{Name}." casts magic missiles, and misses \n";
    }
  }
  else {
    my $hit = $competitor2{POW} + int(rand(10)) + 1 - $competitor1{DEF};
    if($hit > 0){
      my $dmg = int(($competitor2{POW} + int(rand(5)) + 1)/4);
      print $competitor2{Name}." casts magic missiles first, and hits for $dmg \n";
      $competitor1{HP} -= $dmg;
      if($competitor1{HP} < 1){
	$alive = 0;
	next;
      }
    }
    else{
      print $competitor2{Name}." casts magic missiles first, and misses \n";
    }
    $hit = $competitor1{POW} + int(rand(10)) + 1 - $competitor2{DEF};
    if($hit > 0){
      my $dmg = int(($competitor1{POW} + int(rand(5)) + 1)/4);
      print $competitor1{Name}." casts magic missiles, and hits for $dmg \n";
      $competitor2{HP} -= $dmg;
      if($competitor2{HP} < 1){
	$alive = 0;
	next;
      }
    }
    else{
      print $competitor1{Name}." casts magic missiles, and misses \n";
    }
  }
  #Pause the game each round until user input
  my $input = <STDIN>
}
while( my ($k, $v) = each %competitor1 ) {
  print RESULT "$k : $v.\n";
}
while( my ($k, $v) = each %competitor2 ) {
  print RESULT "$k : $v.\n";
}
if($competitor1{HP} > 0){
  print "$competitor1{Name} has won the game \n";
  print RESULT "$competitor1{Name} has won the game \n";
}
else {
  print "$competitor2{Name} has won the game \n";
  print RESULT "$competitor2{Name} has won the game \n";		
}





sub my_read_file {
  my ($compCount, %competitor1, %competitor2, @battleInfo);
  my($fileName, $line);
  
  $fileName = $_[0];
  
  open INFO,"<$fileName" or die $!;

  $line = <INFO>;
  unless(defined $line){
    die "Invalid File";
  }
  my @words = split /\s/,$line;
  #skip if line is a comment
  while($line =~ m/^\#|^[\s]/){
    $line = <INFO>;
    last unless defined $line;
    @words = split /\s/,$line;
  }
  if($words[0] =~ m/^Name:/){
    my $name = "";
    for(my $i = 1; $i < scalar @words; $i++){
      $name .= $words[$i] . " ";
    }
    $competitor1{Name} = $name;
    $line = <INFO>;
    die "Invalid File." unless defined $line;
    @words = split /\s/,$line;
  }
  else{
    die "Invalid file";
  }
  #Add fields to the current hash
  #until the next character is reached
  until($words[0] =~ m/^Name:/){
    # Skip commented line
    last unless defined $line;
    if($line =~ m/^\#|^[\s]/){
      $line = <INFO>;
      last unless defined $line;
      @words = split /\s/,$line;
    }
    #Check for proper field syntax
    elsif($words[0] =~ m/:$/){
      #remove ending : 
      chop $words[0];
      my $content;
      for (my $i = 1; $i < scalar @words; $i++){
	$content .= $words[$i];
      }
      $competitor1{$words[0]} = $content;
      $line = <INFO>;
      die "Not Enough Characters."  unless defined $line;
      @words = split /\s/,$line;
    }
    #Stop if not proper
    else{
      die "Invalid File";
    }
  }
  #Check that the file provides at least POW and DEF
  if(exists $competitor1{POW} && exists $competitor1{DEF}){
    #Check that POW and DEF are digits
    if(($competitor1{POW} =~ m/^[\d]+$/) && ($competitor1{DEF} =~ m/^[\d]+$/)){
      $battleInfo[0] = \%competitor1;
    }
    else {
      die "Invalid File.";
    }
  }
  else {
    die "Invalid File."
  }

  if($words[0] =~ m/^Name:/){
    my $name = "";
    for(my $i = 1; $i < scalar @words; $i++){
      $name .= $words[$i] . " ";
    }
    $competitor2{Name} = $name;
    $line = <INFO>;
    unless(defined $line){
      die "Invalid File.";
    }
    @words = split /\s/,$line;
  }
  else{
    die "Invalid file";
  }
  until($words[0] =~ m/^Name:/ || !(defined $line)){
    if($line =~ m/^\#|^[\s]/){
      $line = <INFO>;
      last unless defined $line;
      @words = split /\s/,$line;
    }
    elsif($words[0] =~ m/:$/){
      chop $words[0];
      my $content;
      for (my $i = 1; $i < scalar @words; $i++){
	$content .= $words[$i];
      }
      $competitor2{$words[0]} = $content;
      $line = <INFO>;
      last unless defined $line;
      @words = split /\s/,$line;
    }
    else{
      die "Invalid File";
    }
  }
  if(exists $competitor2{POW} && exists $competitor2{DEF}){
    if(($competitor2{POW} =~ m/^[\d]+$/) && ($competitor2{DEF} =~ m/^[\d]+$/)){
      $battleInfo[1] = \%competitor2;
    }
    else {
      die "Invalid File.";
    }
  }
  else {
    die "Invalid File"
  }
  
  unless(defined $battleInfo[0] && defined $battleInfo[1]){
    die "Not Enough Characters!";
  }
  return \@battleInfo
}

